package handler

import (
	"2302a/testyuekao/api/resp"
	"2302a/testyuekao/consts"
	"2302a/testyuekao/internal/model"
	"2302a/testyuekao/internal/queue"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
	"log"
	"net/http"
	"strconv"
	"sync"
)

type Message struct {
	FormUserId string `form:"form_user_id" json:"form_user_id"` // 发送者id
	ToUserId   string `form:"to_user_id" json:"to_user_id"`     // 接受者id
}

type Name struct {
	Conn *websocket.Conn
	Data chan []byte
	Mdg  *Message
}

type WSResp struct {
	Code uint        `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data"`
}

var ClineMap map[string]*Name = make(map[string]*Name, 0)

var wg sync.WaitGroup

func Chat(c *gin.Context) {
	var chat Message
	_ = c.ShouldBind(&chat)
	formUserId := chat.FormUserId
	toUserId := chat.ToUserId
	upgrade := websocket.Upgrader{
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}

	conn, err := upgrade.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		log.Printf("WebSocket 连接失败: %v", err)
		//c.JSON(http.StatusUnauthorized,gin.H{})
		resp.Error(c, 401, "WebSocket 连接失败", err.Error())
		return
	} else {
		resp.Success(c, "WebSocket 建立连接成功", true)
	}
	var mrg = &Message{
		FormUserId: formUserId,
		ToUserId:   toUserId,
	}
	node := &Name{
		Conn: conn,
		Data: make(chan []byte, 100),
		Mdg:  mrg,
	}
	ClineMap[formUserId+"_"+toUserId] = node
	wg.Add(2)
	go SendMessage(node, mrg)
	go RecoverMessage(node, mrg)
}

func SendMessage(node *Name, mrg *Message) {
	defer wg.Done()
	//defer node.Conn.Close()
	formUserId := node.Mdg.FormUserId
	toUserId := node.Mdg.ToUserId
	for {
		select {
		case data := <-node.Data:
			atom, _ := strconv.Atoi(mrg.FormUserId)
			fmt.Println(atom)
			//if !pkg.CensorText(string(data)) {
			if atom == 10 {
				_ = node.Conn.WriteMessage(websocket.TextMessage, nil)
			} else {
				err := node.Conn.WriteMessage(websocket.TextMessage, data)
				if err != nil {
					log.Println("消息发送失败", err)
					return
				}
			}
			//} else {
			//	fmt.Println("消息不合法，敏感词禁止")
			//	return
			//}
			go CreatedMessageByAndQueue(formUserId, toUserId, data)

		}
	}
}

func CreatedMessageByAndQueue(formUserId string, toUserId string, data []byte) {
	parseUint, err := strconv.ParseUint(formUserId, 10, 64)
	if err != nil {
		log.Printf("用户ID转换失败：%v", err)
		return
	}
	toParseUint, err := strconv.ParseUint(toUserId, 10, 64)
	if err != nil {
		log.Printf("用户toId转换失败：%v", err)
		return
	}

	//发送消息存入数据库+队列
	go queue.QueueSetPub(consts.QUEUE_PUB, model.Chats{
		FormUserId: uint(parseUint),
		ToUserId:   uint(toParseUint),
		Message:    string(data),
		CType:      1,
	})
}

func RecoverMessage(node *Name, mrg *Message) {
	defer wg.Done()
	for {
		_, message, err := node.Conn.ReadMessage()
		log.Println(message)
		if err != nil {
			log.Println("接受消息失败", err)
			return
		}

		if name, ok := ClineMap[mrg.ToUserId+"_"+mrg.FormUserId]; ok {
			name.Data <- message

		}
		//if name, ok := ClineMap[mrg.FormUserId+"_"+mrg.ToUserId]; ok {
		//	name.Data <- message
		//}

	}
}

func WSRespSuccess(node *Name, data interface{}) {
	response := WSResp{
		Code: http.StatusOK,
		Msg:  "ok",
		Data: data,
	}

	responseStr, _ := json.Marshal(response)

	err := node.Conn.WriteMessage(websocket.TextMessage, responseStr)
	if err != nil {
		log.Println("write:", err)
	}
}
